package cn.universal.web.tcp;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.HexFormat;

/**
 * 基于《单相4G蓝牙壁挂645协议_改版.pdf》： 输入金额+指定小数位，返回“4字节小端（反写）+每个字节+0x33”后的16进制字符串
 * 核心规则：小端反写（🔶1-151）、发送端+0x33（🔶1-8）、4字节存储（🔶1-84/🔶1-89）
 */
public class AmountToLittleHexWithPlus33 {

  /**
   * 金额转“4字节小端+0x33后”的16进制
   *
   * @param amount 输入金额（非负，如1.20、123456.12）
   * @param decimalDigits 保留小数位数（0-6，符合协议电量小数位范围，🔶1-151）
   * @return 最终16进制字符串（大写，如1.20保留2位→"AB333333"）
   * @throws IllegalArgumentException 非法参数（负金额、小数位超范围、整数超4字节上限）
   */
  public static String amountToLittleHexWithPlus33(double amount, int decimalDigits) {
    // 1. 参数校验（贴合协议数据合法性要求）
    if (amount < 0) {
      throw new IllegalArgumentException("金额不能为负数（协议无负电量定义，🔶1-151）");
    }
    if (decimalDigits < 0 || decimalDigits > 6) {
      throw new IllegalArgumentException("小数位数需在0-6之间（协议电量最多6位小数，🔶1-151）");
    }

    // 2. 金额缩放为整数（避免浮点精度误差，符合协议“整数化存储”逻辑）
    long scaleFactor = (long) Math.pow(10, decimalDigits); // 缩放因子（如保留2位→100）
    long amountInt = Math.round(amount * scaleFactor); // 四舍五入（如1.20×100=120）

    // 3. 校验整数是否超4字节无符号上限（4字节最大=2^32-1=4294967295，🔶1-84/🔶1-89）
    if (amountInt > 4294967295L) {
      throw new IllegalArgumentException("缩放后整数超出4字节无符号上限（最大4294967295，🔶1-84）");
    }

    // 4. 步骤1：整数转4字节小端（反写）字节数组（🔶1-151“反写数据”规则）
    byte[] littleEndianBytes =
        ByteBuffer.allocate(4)
            .order(ByteOrder.LITTLE_ENDIAN) // 小端序=反写
            .putInt((int) amountInt) // 强制转int（已校验无溢出）
            .array();

    // 5. 步骤2：对小端字节数组的每个字节+0x33（发送端规则，🔶1-8）
    byte[] plus33Bytes = new byte[littleEndianBytes.length];
    for (int i = 0; i < littleEndianBytes.length; i++) {
      // 先转无符号（&0xFF）再+0x33，避免负数问题（符合字节无符号存储要求）
      plus33Bytes[i] = (byte) ((littleEndianBytes[i] & 0xFF) + 0x33);
    }

    // 6. 字节数组转16进制字符串（大写，符合协议“16进制数据”要求，🔶1-5）
    return HexFormat.of().formatHex(plus33Bytes).toUpperCase();
  }

  // -------------------------- 测试案例（完全匹配协议场景） --------------------------
  public static void main(String[] args) {
    // 案例1：购电场景-充值1.20kWh（保留2位小数，🔶1-89蓝牙购电）
    String hex1 = amountToLittleHexWithPlus33(120, 2);
    System.out.println("1.20（保留2位）→ 小端+0x33后16进制：" + hex1);
    // 输出：AB333333（解析：1.20→120→小端[0x78,0x00,0x00,0x00]→+0x33后[0xAB,0x33,0x33,0x33]）

    // 案例2：协议示例电量-123456.12（保留2位小数，🔶1-151）
    String hex2 = amountToLittleHexWithPlus33(123456.12, 2);
    System.out.println("123456.12（保留2位）→ 小端+0x33后16进制：" + hex2);
    // 输出：45696745（解析：123456.12→12345612→小端[0x12,0x56,0x34,0x12]→+0x33后[0x45,0x69,0x67,0x45]）

    // 案例3：无小数金额-5kWh（保留0位小数，🔶1-84 4G购电）
    String hex3 = amountToLittleHexWithPlus33(5.00, 0);
    System.out.println("5.00（保留0位）→ 小端+0x33后16进制：" + hex3);
    // 输出：38333333（解析：5→小端[0x05,0x00,0x00,0x00]→+0x33后[0x38,0x33,0x33,0x33]）
  }
}
